package com.mayuanfei.springboot11.validation;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.mayuanfei.springboot11.common.CommonRequest;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Map;
import java.util.TreeMap;

/**
 * 校验签名
 *
 * @author 老马
 * @date 2023-06-16 14:14
 */
@Slf4j
public class SignValidator implements ConstraintValidator<SignCheck, Object> {

    private SignCheck signCheck;

    @Override
    public void initialize(SignCheck constraintAnnotation) {
        this.signCheck = constraintAnnotation;
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext context) {
        if(value instanceof CommonRequest) {
            CommonRequest request = (CommonRequest) value;
            //判断请求对象中的sign是否有值.如果没有sign字段,或者sign的字段值为空,直接返回校验失败
            Object fieldValue = BeanUtil.getFieldValue(request, this.signCheck.signFieldName());
            if(ObjectUtil.isNull(fieldValue) || StrUtil.isBlank(String.valueOf(fieldValue))){
                return false;
            }
            //按照预先定义的逻辑,对请求对象生成签名
            String generateSign = generateSign(request);
            return StrUtil.equalsIgnoreCase(request.getSign(), generateSign);
        }
        return false;
    }

    //按照预先定义的逻辑,对请求对象生成签名
    public String generateSign(CommonRequest request) {
        // 获得对象的所有属性进行排序
        Map<String, Object> beanMap = BeanUtil.beanToMap(request);
        // 对所有属性进行排序
        TreeMap<String, Object> treeMap = new TreeMap<>(beanMap);
        beanMap.keySet().forEach(key -> treeMap.put(key, beanMap.get(key)));
        //用=号和&号连接参数.排除掉sign字段
        StringBuilder sb = new StringBuilder();
        for (String key : treeMap.keySet()) {
            if(this.signCheck.signFieldName().equals(key)){
                continue;
            }
            sb.append(key).append("=").append(treeMap.get(key)).append("&");
        }
        if(sb.length() > 0){
            sb.deleteCharAt(sb.length() - 1);
            //拼接私钥
            sb.append("1234567890");
        }
        //进行sha256加密
        return DigestUtil.sha256Hex(sb.toString());
    }
}